package org.amphiption.gametimer.screen;

import java.util.Random;

import org.amphiption.gametimer.R;
import org.amphiption.gametimer.entity.TimerConfiguration;
import org.amphiption.gametimer.entity.TimerConfiguration.TimerType;
import org.amphiption.gametimer.screen.component.PlayerComponent;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.animation.BounceInterpolator;

import com.amphiprion.prototype.GameScreen;
import com.amphiprion.prototype.component.ButtonComponent;
import com.amphiprion.prototype.component.IActionListener;
import com.amphiprion.prototype.component.TextComponent;
import com.amphiprion.prototype.component.animation.AlplaComponentAnimation;
import com.amphiprion.prototype.component.animation.ScaleComponentAnimation;
import com.amphiprion.prototype.control.ControlerState;
import com.amphiprion.prototype.control.ControlerState.ClickMode;
import com.amphiprion.prototype.util.BitmapUtil;
import com.amphiprion.prototype.util.NormalizedBitmap;

public class PlaySessionScreen extends GameScreen {
	private enum ScreenState {
		NONE, DEFINE_PLACE_ENTER, CHOOSE_FIRST_PLAYER
	}

	private Random rnd = new Random();
	private TimerConfiguration tc;

	private ScreenState screenState = ScreenState.NONE;
	private NormalizedBitmap background;
	private PlayerComponent[] playerComponents;
	private PlayerComponent movingPlayer;
	private boolean allDocked = false;
	private ButtonComponent firstPlayer;

	public PlaySessionScreen(final Context context, TimerConfiguration tc) {
		super(context);
		this.tc = tc;

		firstPlayer = new ButtonComponent("first.png", getReferenceWidth() / 2, getReferenceHeight() / 2, 0);
		addComponent(firstPlayer);

		playerComponents = new PlayerComponent[tc.getPlayers().size()];
		int offx = -7 * (playerComponents.length - 1) / 2;
		int offy = +15 * (playerComponents.length - 1) / 2;
		for (int i = 0; i < playerComponents.length; i++) {
			final PlayerComponent pc = new PlayerComponent(tc.getPlayers().get(i), getReferenceWidth() / 2 + offx + 7 * i, getReferenceHeight() / 2 + offy - 15 * i,
					tc.getTimerType() == TimerType.TURN_COUNTER);
			playerComponents[i] = pc;

			addComponent(pc);
		}

		gotoStartDefinePlace();
	}

	protected void startMoving(PlayerComponent pc) {
		movingPlayer = pc;
		allDocked = false;
		firstPlayer.clearAnimations();
		firstPlayer.setAlpha(0);

	}

	@Override
	public void onInput(ControlerState state, long elpased) {
		if (movingPlayer == null) {
			super.onInput(state, elpased);
			if (screenState == ScreenState.DEFINE_PLACE_ENTER) {
				if (allDocked && state.click == ClickMode.DOWN && firstPlayer.isInside(state.position.x, state.position.y)) {
					firstPlayer.addAnimation(new AlplaComponentAnimation(200, 0, 255, 0));
					postDelayed(new Runnable() {
						@Override
						public void run() {
							gotoChooseFirstPlayer();
						}
					}, 200);
				}
			}
		} else if (state.touched) {
			movingPlayer.setX(state.position.x);
			movingPlayer.setY(state.position.y);
			if (state.position.x <= movingPlayer.getHeight() * 2) {
				movingPlayer.setRotation(+90);
				movingPlayer.setX(movingPlayer.getHeight() / 2.0f);
				movingPlayer.setDocked(true);
			} else if (state.position.x >= getReferenceWidth() - movingPlayer.getHeight() * 2) {
				movingPlayer.setRotation(-90);
				movingPlayer.setX(getReferenceWidth() - movingPlayer.getHeight() / 2.0f);
				movingPlayer.setDocked(true);
			} else if (state.position.y <= movingPlayer.getHeight() * 2) {
				movingPlayer.setRotation(180);
				movingPlayer.setY(movingPlayer.getHeight() / 2.0f);
				movingPlayer.setDocked(true);
			} else if (state.position.y >= getReferenceHeight() - movingPlayer.getHeight() * 2) {
				movingPlayer.setRotation(0);
				movingPlayer.setY(getReferenceHeight() - movingPlayer.getHeight() / 2.0f);
				movingPlayer.setDocked(true);
			} else {
				movingPlayer.setRotation(0);
				movingPlayer.setDocked(false);
			}
		} else {
			movingPlayer = null;

			boolean all = true;
			for (PlayerComponent pc : playerComponents) {
				if (!pc.isDocked()) {
					all = false;
				}
			}
			allDocked = all;
			if (allDocked) {
				firstPlayer.addAnimation(new AlplaComponentAnimation(800, 0, 0, 255));
				firstPlayer.addAnimation(new ScaleComponentAnimation(800, 0, .2f, 1.f, new BounceInterpolator()));
			}
		}
	}

	private void gotoChooseFirstPlayer() {
		firstPlayer.setAlpha(0);

		final TextComponent txt = new TextComponent(getStringArray(R.array.choose_first_player), 25.0f, Color.WHITE, getReferenceWidth() / 2.0f, getReferenceHeight() / 2.0f, 0, 0);
		txt.addAnimation(new AlplaComponentAnimation(1000, 0, 0, 255));
		addComponent(txt);

		final ButtonComponent btrnd = new ButtonComponent("random.png", getReferenceWidth() / 2, getReferenceHeight() / 2 + 120, 0);
		btrnd.addAnimation(new AlplaComponentAnimation(1000, 0, 0, 255));
		addComponent(btrnd);
		btrnd.setActionListener(new IActionListener() {
			@Override
			public void actionPerformed(Object source) {
				if (screenState == ScreenState.CHOOSE_FIRST_PLAYER) {
					view.addScreen(new TimingSessionScreen(getContext(), tc, playerComponents, playerComponents[rnd.nextInt(playerComponents.length)]));
				}
			}
		});
		for (int i = 0; i < playerComponents.length; i++) {
			final int index = i;
			final PlayerComponent pc = playerComponents[i];
			pc.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					if (screenState == ScreenState.CHOOSE_FIRST_PLAYER) {
						view.addScreen(new TimingSessionScreen(getContext(), tc, playerComponents, playerComponents[index]));
					}
				}
			});

		}

		screenState = ScreenState.CHOOSE_FIRST_PLAYER;
	}

	@Override
	protected float getReferenceWidth() {
		return 480;
	}

	@Override
	protected float getReferenceHeight() {
		return 800;
	}

	@Override
	protected boolean isLandscape() {
		return false;
	}

	@Override
	protected void onPreDraw(Canvas canvas) {
		if (background != null) {
			drawImage(canvas, background.bitmap, getReferenceWidth() / 2, getReferenceHeight() / 2, 1.0f);
		}
	}

	@Override
	protected void onPostDraw(Canvas canvas) {

	}

	@Override
	public void activate() {
		background = BitmapUtil.loadBitmap("table.png");
		super.activate();
	}

	@Override
	public void desactivate() {
		BitmapUtil.unloadBitmap("table.png");
		super.desactivate();
	}

	private void gotoStartDefinePlace() {
		allDocked = false;
		firstPlayer.setAlpha(0);
		int offx = -7 * (playerComponents.length - 1) / 2;
		int offy = +15 * (playerComponents.length - 1) / 2;
		for (int i = 0; i < playerComponents.length; i++) {
			final PlayerComponent pc = playerComponents[i];
			pc.setX(getReferenceWidth() / 2 + offx + 7 * i);
			pc.setY(getReferenceHeight() / 2 + offy - 15 * i);
			pc.setActionListener(new IActionListener() {
				@Override
				public void actionPerformed(Object source) {
					if (screenState == ScreenState.DEFINE_PLACE_ENTER && movingPlayer == null) {
						startMoving(pc);
					}
				}
			});
		}
		screenState = ScreenState.DEFINE_PLACE_ENTER;
	}

	@Override
	public boolean onBackRequested() {
		return false;
	}
}
